<script setup lang="ts">
import { onMounted, ref, defineProps } from 'vue'
import * as Cesium from 'cesium'
// import { NetCDFReader } from 'netcdfjs'
import h337 from 'heatmap.js'
import { saltInfo } from '@/api/saltNc'
import { tempInfo } from '@/api/tempNc'
import { soundInfo } from '@/api/soundNc'
import { densityInfo } from '@/api/densityNc'
import measureLineSpace from "@/utils/measure.js"
import CesiumHeatMap3D from 'cesiumheatmap3d';

import TooltipDiv from "./tooltip.js";

Cesium.Ion.defaultAccessToken =
  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyNjI1NzQyYS00NjA0LTQ1OGQtOGU0Ni1jZTk5ODY2NGM2NjkiLCJpZCI6MjE4MDQ0LCJpYXQiOjE3MTY3OTI3OTN9.2Tjns8eg13V53NnIRIJRClnIkrv9gqFAY_OyUDB9N-M'

let viewerRef = null
let heatmapRef = null
let sceneRef = null
let dvalue = ref("")
let maxValue = ref(40);
let minValue = ref(0);

// 观测网络
const prop = defineProps(['networkTree', 'lineArr'])

const emit = defineEmits(['updateLonLat'])

onMounted(async () => {
  const viewer = new Cesium.Viewer('cesiumContainer', {
    animation: false, //是否创建动画小器件，左下角仪表
    timeline: false, //是否显示时间线控件
    fullscreenButton: false, //右下角全屏按钮
    vrButton: false, //右下角vr虚拟现实按钮
    geocoder: false, //是否显示地名查找控件
    sceneModePicker: false, //是否显示投影方式控件
    homeButton: false, //回到默认视域按钮
    navigationHelpButton: false, //是否显示帮助信息控件

    baseLayerPicker: false, //是否显示图层选择控件

    // 2d 3d 切换
    // terrainProvider: await Cesium.createWorldBathymetryAsync({
    //   requestVertexNormals: true
    // }),
    orderIndependentTranslucency: false,
    contextOptions: {
      webgl: {
        alpha: true
      }
    }
  })

  // 观测网络 start
  // 初始化Tooltip 
  TooltipDiv.initTool(viewer.cesiumWidget.container);
  // 创建ScreenSpaceEventHandler处理鼠标移动事件
  var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
  handler.setInputAction(function(movement) {
      var pick = viewer.scene.pick(movement.endPosition);
      if (Cesium.defined(pick) && pick.id !== TooltipDiv) {
        if(pick.id?._data?.showTooltip) {
          TooltipDiv.show(movement.endPosition, '<table style="min-width: 200px;"><tr>'
          + '<td width="50">名称：</td><td class="w-auto">' + pick.id._data.label + '</td></tr><tr>'
          + '<td width="50">位置：</td><td class="w-auto">' + pick.id._data.position + '</td></tr>'
          + '</table>');
          viewer.canvas.style.cursor = "pointer"; // 鼠标悬停在 billboard 上时显示手形光标
        } else {
          TooltipDiv.hide(false);
        }
      } else {
        TooltipDiv.hide(false);
        viewer.canvas.style.cursor = "default"; // 否则显示默认光标
      }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  const deviceArr = []
  const initWork = () => {
    // 循环画出所有的点 + 弹窗
    // 海洋【不用循环】
    // addFeature(prop.networkTree, 1)
    prop.networkTree.forEach((firstItem) => {
      // 平台
      addFeature(firstItem.children, 2)
      firstItem.children.forEach((secondItem) => {
        // 设备
        deviceArr.push(...secondItem.children)
      })
    })

    addFeature(deviceArr, 3)

    // 循环画出所有的线
    for (let i = 0; i < prop.lineArr.length; i++) {
      let item = prop.lineArr[i]
      for (let j = 0; j < item.length; j++) {
        viewer.entities.add({
          name: '光缆',
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArray(item[j]),
            width: 3,
            material: new Cesium.PolylineOutlineMaterialProperty({
              color: Cesium.Color.WHITE,
              outlineWidth: 0,
              outlineColor: Cesium.Color.WHITE,
            })
          }
        })
      }
    }

    var dataSource
    // 添加不同颜色的点和tooltip
    function addFeature(arr, order) {
      dataSource = new Cesium.CustomDataSource()
      for (var i = 0, len = arr.length; i < len; i++) {
        var item = arr[i]


        //添加实体
        // 平台
        if(order == 2) {
          dataSource.entities.add({
            name: item.label,
            position: Cesium.Cartesian3.fromDegrees(item.position[0], item.position[1]),
            point: {
              color: Cesium.Color.fromCssColorString('#ff4400'),
              pixelSize: 30 - 8,
              outlineColor: Cesium.Color.WHITE,
              outlineWidth: 4,
              // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
            },
            data: item,
          })
        }
        // 设备
        else if(order == 3) {
          dataSource.entities.add({
            name: item.label,
            position: Cesium.Cartesian3.fromDegrees(item.position[0], item.position[1]),
            point: {
              color: Cesium.Color.WHITE,
              pixelSize: 30 - 8,
              outlineColor: Cesium.Color.fromCssColorString('#000000'),
              outlineWidth: 4,
              // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
            },
            data: item,
          })
        }

      }

      //========聚合 start==========
      dataSource.clustering.enabled = true
      dataSource.clustering.pixelRange = 20 //多少像素矩形范围内聚合

      dataSource.clustering.clusterEvent.addEventListener(function (clusteredEntities, cluster) {
        var count = clusteredEntities.length
        cluster.label.show = false
        cluster.billboard.show = true
        cluster.billboard.id = cluster.label.id
        cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM
        drawClusterBillboard(cluster.billboard, count, '', clusteredEntities)
      })
      //========聚合 end==========

      viewer.dataSources.add(dataSource)
    }



    // 绘制聚合点
    function drawClusterBillboard(billboard, size, label, clusteredEntities) {
      if (!label) {
        label = size
      }

      let sizeInner = 30
      // 放大倍数（放大后会再缩小回去，倍数越高图片会越清晰一些。）
      let scale = 2
      sizeInner *= scale
      // sizeInner += 4 * scale;
      // 创建画布对象
      let canvas = document.createElement('canvas')
      canvas.width = sizeInner
      canvas.height = sizeInner
      let ctx = canvas.getContext('2d')
      // 渲染圆圈
      ctx.arc(sizeInner / 2, sizeInner / 2, sizeInner / 2 - 2 * scale, 0, 2 * Math.PI)

      ctx.fillStyle = 'rgba(255, 255, 255, 1)'
      ctx.strokeStyle = '#000000'

      ctx.lineWidth = (2 + 2) * scale
      ctx.fill()
      ctx.stroke()
      // 渲染字体
      ctx.fillStyle = '#000000'
      ctx.font = 'normal ' + (20 - 5) * scale + 'px sans-serif'
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.fillText(label, sizeInner / 2, sizeInner / 2 + 2 * scale)
      billboard.image = canvas
      billboard.scale = 1 / scale

      //增加参数
      billboard.id = {
        type: 'cluster',
        clusteredEntities
      }
    }
  }
  initWork()
  // 观测网络 end

  // 添加点击事件监听器
  var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
  handler.setInputAction(function (click) {
    // 获取点击位置的经纬度
    var pickedObject = viewer.scene.pickPosition(click.position)
    if (Cesium.defined(pickedObject)) {
      var cartesian = viewer.scene.pickPosition(click.position)
      var cartographic = Cesium.Cartographic.fromCartesian(cartesian)
      var longitude = Cesium.Math.toDegrees(cartographic.longitude)
      var latitude = Cesium.Math.toDegrees(cartographic.latitude)
      // lon.value = longitude
      // lat.value = latitude
      emit('updateLonLat', [longitude, latitude])
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

  viewer.imageryLayers.remove(viewer.imageryLayers.get(0))

  // 叠加影像服务
  var imgMap = new Cesium.UrlTemplateImageryProvider({
    url: 'https://t4.tianditu.gov.cn/ter_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ter&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=6fff081965d4bf0bf850c2b6e94c82f4',
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    maximumLevel: 18
  })
  viewer.imageryLayers.addImageryProvider(imgMap)

  // 叠加影像服务
  var imgMap2 = new Cesium.UrlTemplateImageryProvider({
    url: 'https://t5.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=6fff081965d4bf0bf850c2b6e94c82f4',
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    maximumLevel: 18
  })
  viewer.imageryLayers.addImageryProvider(imgMap2)

  //   var imgMap3 = new Cesium.WebMapServiceImageryProvider({
  //     url: 'https://wms.gebco.net/2021/mapserv',
  //     layers: 'gebco_2021_2',
  //     format: 'image/jpeg'
  //   });
  // viewer.imageryLayers.addImageryProvider(imgMap3);

  const scene = viewer.scene
  sceneRef = scene

  // prevent aliasing from countour lines
  scene.msaaSamples = 4

  const globe = scene.globe
  globe.enableLighting = true
  globe.maximumScreenSpaceError = 1.0 // Load higher resolution tiles for better seafloor shading

  // Sandcastle.addToggleButton("Lighting enabled", true, function (
  //   checked
  // ) {
  //   globe.enableLighting = checked;
  // });

  // Light the scene with a hillshade effect similar to https://pro.arcgis.com/en/pro-app/latest/tool-reference/3d-analyst/how-hillshade-works.htm
  scene.light = new Cesium.DirectionalLight({
    direction: new Cesium.Cartesian3(1, 0, 0) // Updated every frame
  })

  scene.verticalExaggeration = 1

  const camera = scene.camera
  const cameraMaxHeight = globe.ellipsoid.maximumRadius * 2
  const scratchNormal = new Cesium.Cartesian3()
  scene.preRender.addEventListener(function (scene, time) {
    const surfaceNormal = globe.ellipsoid.geodeticSurfaceNormal(camera.positionWC, scratchNormal)
    const negativeNormal = Cesium.Cartesian3.negate(surfaceNormal, surfaceNormal)
    scene.light.direction = Cesium.Cartesian3.normalize(
      Cesium.Cartesian3.add(negativeNormal, camera.rightWC, surfaceNormal),
      scene.light.direction
    )

    const zoomMagnitude = Cesium.Cartesian3.magnitude(camera.positionWC) / cameraMaxHeight

    updateGlobeMaterialUniforms(zoomMagnitude)
  })

  // Sandcastle.addToggleButton("Fog enabled", true, (checked) => {
  //   scene.fog.enabled = checked;
  //   globe.showGroundAtmosphere = checked;
  // });

  // Globe materials
  let showContourLines = true
  let invertContourLines = true

  const countourLineSpacing = 500.0

  function updateGlobeMaterialUniforms(zoomMagnitude) {
    const material = globe.material
    if (!Cesium.defined(material)) {
      return
    }

    const spacing = 5.0 * Math.pow(10, Math.floor(4 * zoomMagnitude))
    if (showContourLines) {
      const uniforms = material.uniforms

      uniforms.spacing = spacing * scene.verticalExaggeration
    }
  }

  function updateGlobeMaterial() {
    let material
    if (showContourLines) {
      material = Cesium.Material.fromType('ElevationContour')
      const shadingUniforms = material.uniforms
      shadingUniforms.width = 1.0
      shadingUniforms.spacing = countourLineSpacing * scene.verticalExaggeration
      shadingUniforms.color = invertContourLines ? Cesium.Color.WHITE : Cesium.Color.BLACK
      globe.material = material
      return
    }

    globe.material = material
  }

  updateGlobeMaterial()

  //#region
  // scene.camera.setView({
  //   destination: Cesium.Cartesian3.fromDegrees(109.86451388751524, 12.043487135813335, 15672),
  //   orientation: new Cesium.HeadingPitchRoll(
  //     6.266986092693175,
  //     -0.34262046104451316,
  //     6.283182056027252
  //   ),
  // });
  //
  // viewer.entities.add({
  //   polygon: {
  //     hierarchy: new Cesium.PolygonHierarchy(
  //       Cesium.Cartesian3.fromDegreesArray(
  //         [
  //           109.83451388751522, 12.543487135813331,
  //           109.93451388751522, 12.543487135813331,
  //           109.93451388751522, 12.443487135813331,
  //           109.83451388751522, 12.443487135813331
  //         ]
  //       )
  //     ),
  //     material: Cesium.Color.RED.withAlpha(0.5),
  //     height: 0
  //   }
  // });
  // function randomColorString () {
  //   let num = Math.floor(Math.random() * Math.floor(3));
  //   switch (num) {
  //     case 1:
  //       return 'rgba(0,255,127,0.5)'
  //     case 2:
  //       return 'rgba(255,215,0,0.5)'
  //     default:
  //       return 'rgba(0,0,255,0.5)'
  //   }
  // }
  //
  // for (var i = 0; i < 20; i++) {
  //   const x = 109.83451388751522 + (0.1 * Math.random());
  //   const y = 12.443487135813331 + (0.1 * Math.random());
  //   let h = 0;
  //   while (h > -3000) {
  //     h = h - 400 - (100 * Math.random())
  //     viewer.entities.add({
  //       position: Cesium.Cartesian3.fromDegrees(x, y),
  //       ellipse: {
  //         semiMinorAxis: 260.0,
  //         semiMajorAxis: 260.0,
  //         extrudedHeight: h + 150,
  //         height: h,
  //         material: Cesium.Color.fromCssColorString(randomColorString()),
  //       }
  //     });
  //   }
  // }
  //#endregion

  // 3d
  // getNCFileInfoV2(scene, viewer)

  // 全局
  viewerRef = viewer
})

// 3d 数据
// const getNCFileInfoV2 = (scene, viewer) => {
//   const dataMap = []
//   let minLat = 90
//   let maxLat = -90
//   let minLng = 180
//   let maxLng = -180
//   let n = 0
//   for (var i = 0; i < 8; i++) {
//     const no = i
//     const xhr = new XMLHttpRequest()
//     xhr.open('get', `/seabed2/2900313/profiles/D2900313_${(i + '').padStart(3, '0')}.nc`, true)
//     // xhr.open("get", `/seabed2/2900457/profiles/D2900457_${(i+'').padStart(3, '0')}.nc`, true)
//     xhr.responseType = 'arraybuffer'
//     xhr.onload = () => {
//       const reader = new NetCDFReader(xhr.response)

//       const lat = Number(reader.getDataVariable('LATITUDE')[0])
//       const lng = Number(reader.getDataVariable('LONGITUDE')[0])
//       if (minLat > lat) {
//         minLat = lat
//       }
//       if (maxLat < lat) {
//         maxLat = lat
//       }
//       if (minLng > lng) {
//         minLng = lng
//       }
//       if (maxLng < lng) {
//         maxLng = lng
//       }
//       const d = {
//         name: reader.getDataVariable('PLATFORM_NUMBER').join('') + '_' + no,
//         lat: lat,
//         lng: lng,
//         temp: reader.getDataVariable('TEMP'),
//         pres: reader.getDataVariable('PRES'),
//         psal: reader.getDataVariable('PSAL')
//       }
//       dataMap.push(d)

//       n++
//       if (n >= 8) {
//         setCameraPosition(scene, minLat + (maxLat - minLat) / 2, minLng + (maxLng - minLng) / 2)
//         makeSeaLevelV2(viewer, minLat, maxLat, minLng, maxLng)
//         setDataV2(viewer, dataMap)
//       }
//     }
//     xhr.send(null)
//   }
// }

//#region
// const getNCFileInfo = (scene, viewer) => {
//   const xhr = new XMLHttpRequest()
//   xhr.open('get', '/seabed2/2900313/profiles/D2900313_000.nc', true)
//   xhr.responseType = 'arraybuffer'
//   xhr.onload = () => {
//     const reader = new NetCDFReader(xhr.response)
//     const lat = reader.getDataVariable('LATITUDE')[0]
//     const log = reader.getDataVariable('LONGITUDE')[0]
//     setCameraPosition(scene, lat, log)
//     makeSeaLevel(viewer, lat, log)
//     const name = reader.getDataVariable('PLATFORM_NUMBER')
//     const temp = reader.getDataVariable('TEMP')
//     const pres = reader.getDataVariable('PRES')
//     const psal = reader.getDataVariable('PSAL')
//     const data = {}
//     for (var i = 0; i < pres.length; i++) {
//       data[pres[i]] = {
//         temp: temp[i],
//         psal: psal[i]
//       }
//     }
//     setData(viewer, lat, log, data, name.join(''))
//   }
//   xhr.send(null)
// }
//#endregion

// 3d 视角定位
// const setCameraPosition = (scene, lat, log) => {
//   scene.camera.setView({
//     destination: Cesium.Cartesian3.fromDegrees(log, lat - 1.2, 50000),
//     orientation: new Cesium.HeadingPitchRoll(
//       6.266986092693175,
//       -0.34262046104451316,
//       6.283182056027252
//     )
//   })
// }

// #region
// const makeSeaLevel = (viewer, lat, log) => {
//   viewer.entities.add({
//     name: '海平面',
//     polygon: {
//       hierarchy: new Cesium.PolygonHierarchy(
//         Cesium.Cartesian3.fromDegreesArray([
//           log + 0.003,
//           lat + 0.003,
//           log - 0.003,
//           lat + 0.003,
//           log - 0.003,
//           lat - 0.003,
//           log + 0.003,
//           lat - 0.003
//         ])
//       ),
//       material: Cesium.Color.RED.withAlpha(0.5),
//       height: 0,
//       disableClicking: true
//     }
//   })
// }
//#endregion

// 3d 海平面纯色
// const makeSeaLevelV2 = (viewer, minlat, maxlat, minlng, maxlng) => {
//   viewer.entities.add({
//     name: '海平面',
//     polygon: {
//       hierarchy: new Cesium.PolygonHierarchy(
//         Cesium.Cartesian3.fromDegreesArray([
//           minlng,
//           minlat,
//           maxlng,
//           minlat,
//           maxlng,
//           maxlat,
//           minlng,
//           maxlat
//         ])
//       ),
//       material: Cesium.Color.RED.withAlpha(0.5),
//       height: 0,
//       disableClicking: true
//     }
//   })
// }

//#region
// const setData = (viewer, lat, log, data, name) => {
//   for (let key in data) {
//     viewer.entities.add({
//       name: `${name}__${key}`,
//       position: Cesium.Cartesian3.fromDegrees(log, lat, key * -1),
//       ellipsoid: {
//         radii: new Cesium.Cartesian3(5.0, 5.0, 5.0),
//         material: Cesium.Color.fromCssColorString('rgba(0,0,255,0.4)')
//       },
//       description: `\<ul>\<li>PRES: ${key}</li>\<li>TEMP: ${data[key]['temp']}</li>\<li>PSAL: ${data[key]['psal']}</li></ul>`
//     })
//   }
// }
//#endregion

// 3d 深度柱形图
// const setDataV2 = (viewer, data) => {
//   for (var i = 0; i < data.length; i++) {
//     const item = data[i]
//     for (var j = 0; j < item['pres'].length; j++) {
//       viewer.entities.add({
//         name: `${item['name']}__${item['pres'][j]}`,
//         position: Cesium.Cartesian3.fromDegrees(item['lng'], item['lat'], item['pres'][j] * -1),
//         ellipsoid: {
//           radii: new Cesium.Cartesian3(500.0, 500.0, 5.0),
//           material: Cesium.Color.fromCssColorString('rgba(0,0,255,0.4)')
//         },
//         description: `\<ul>\<li>PRES: ${item['pres'][j]}</li>\<li>TEMP: ${item['temp'][j]}</li>\<li>PSAL: ${item['psal'][j]}</li></ul>`
//       })
//     }
//   }
// }
let heatmapInstance2 = null;
const heatMap2 = (viewer, apiData) => {
  // 使用reduce方法找到val的最大值
  let max = apiData.reduce((maxValue, currentObject) => {
    return Math.max(maxValue, currentObject.value)
  }, -Infinity)
  maxValue.value = max
  // 使用reduce方法找到val的最大值
  let min = apiData.reduce((maxValue, currentObject) => {
    return Math.min(maxValue, currentObject.value)
  }, Infinity)
  minValue.value = min
  // console.log(max, min)

  const latMin =
    apiData.reduce((maxValue, currentObject) => {
      return Math.min(maxValue, currentObject.latitude)
    }, Infinity)

  const latMax =
    apiData.reduce((maxValue, currentObject) => {
      return Math.max(maxValue, currentObject.latitude)
    }, -Infinity)

  const lonMin =
    apiData.reduce((maxValue, currentObject) => {
      return Math.min(maxValue, currentObject.longitude)
    }, Infinity)

  const lonMax =
    apiData.reduce((maxValue, currentObject) => {
      return Math.max(maxValue, currentObject.longitude)
    }, -Infinity)
  var data = [];
  let len = apiData.length
  for (let i = 0; i < len; i++) {
    // 传进原始数据
    let dataItem = apiData[i]
    data.push({
      lon: dataItem.longitude,
      lat: dataItem.latitude,
      value: dataItem.value
    })
  }
  if (heatmapInstance2 != null) {
    heatmapInstance2.removeDate();
    heatmapInstance2 = null;
  }
  heatmapInstance2 = new CesiumHeatMap3D(
    viewer,
    [lonMin, latMin, lonMax, latMax],
    {
      blur: 1,
      radius: 25,
      maxOpacity: 0.5,
      minOpacity: 0.01,
      gradient: {
        0.01: 'rgb(0,0,255)',
        0.33: 'rgb(0,255,0)',
        0.66: 'rgb(255,255,0)',
        1.0: 'rgb(255,0,0)'
      },
    },
    {
      baseHeight: 0,
      heightGradient: 0
    }
  );

  heatmapInstance2.setData(data, min, max)
  // 取景器镜头聚焦到热力图实例上
  viewerRef.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(
      lonMin + (lonMax - lonMin) / 2,
      latMin + (latMax - latMin) / 2,
      5000000
    ),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: 0
    }
  })
}
// 热力图
const heatMap = (viewer, apiData) => {
  // 使用reduce方法找到val的最大值
  let max = apiData.reduce((maxValue, currentObject) => {
    return Math.max(maxValue, currentObject.value)
  }, -Infinity)
  maxValue.value = max
  // 使用reduce方法找到val的最大值
  let min = apiData.reduce((maxValue, currentObject) => {
    return Math.min(maxValue, currentObject.value)
  }, Infinity)
  minValue.value = min
  // console.log(max, min)

  const latMin =
    apiData.reduce((maxValue, currentObject) => {
      return Math.min(maxValue, currentObject.latitude)
    }, Infinity) - 20

  const latMax =
    apiData.reduce((maxValue, currentObject) => {
      return Math.max(maxValue, currentObject.latitude)
    }, -Infinity) + 20

  const lonMin =
    apiData.reduce((maxValue, currentObject) => {
      return Math.min(maxValue, currentObject.longitude)
    }, Infinity) - 20

  const lonMax =
    apiData.reduce((maxValue, currentObject) => {
      return Math.max(maxValue, currentObject.longitude)
    }, -Infinity) + 20

  /* 初始化热力图设置 */
  // 设置随机数据点数量
  let len = apiData.length
  // 构建随机数据点
  let points = []
  // 设置热力图宽度和高度
  let width = 1920
  let height = 1080
  // // 设置纬度最低点和最高点
  // let latMin = 28.364807
  // let latMax = 40.251095
  // // 设置经度最低点和最高点
  // let lonMin = 94.389228
  // let lonMax = 108.666357
  // 准备一个装原始数据的数组
  let dataRaw = []
  // 设置每个点包含的元素（属性）
  for (let i = 0; i < len; i++) {
    let point = {
      // 在设定的经纬度区间选取随机数作为每个点的经纬度
      lat: apiData[i].latitude,
      lon: apiData[i].longitude,
      // 在0到最大值之间向下取整选取随机数作为每个点的值
      value: apiData[i].value
    }
    // 将设置好的点加入数组
    dataRaw.push(point)
  }
  // 将每个点的元素（属性？）转换为创建h337对象即热力图实例所需的数据格式
  for (let i = 0; i < len; i++) {
    // 传进原始数据
    let dataItem = dataRaw[i]
    let point = {
      // 将数据点经纬度等比例设置成矩形中的x y坐标 值为原始数据的值
      x: Math.floor(((dataItem.lat - latMin) / (latMax - latMin)) * width),
      y: Math.floor(((dataItem.lon - lonMin) / (lonMax - lonMin)) * height),
      value: dataItem.value
    }
    // 比较设置的最大值和原始数据值大小 取两者间的最大值
    max = Math.max(max, dataItem.value)

    // 将转换好后的数据存入数组
    points.push(point)
  }

  // 创建热力图实例
  let heatMapInstance = h337.create({
    container: document.querySelector('#heatMap'),
    radius: 10,
    maxOpacity: 0.5,
    minOpacity: 0.01,
    blur: 0,
    gradient: {
      0.25: 'rgb(0,0,255)',
      0.55: 'rgb(0,255,0)',
      0.85: 'rgb(255,255,0)',
      1.0: 'rgb(255,0,0)'
    }
  })
  // 设置传入实例的数据
  let data = {
    max: max,
    min: min,
    data: points
  }

  // 新建热力图实例并传入设置好的数据
  heatMapInstance.setData(data)
  // 设置画布为生成的热力图
  let canvas = document.getElementsByClassName('heatmap-canvas')

  // 添加热力图实例
  heatmapRef = viewer.entities.add({
    name: 'heatmap',
    // 设置矩形
    rectangle: {
      // 指定矩形区域
      coordinates: Cesium.Rectangle.fromDegrees(lonMin, latMin, lonMax, latMax),
      // 设置矩形图片为据透明度的热力图
      material: new Cesium.ImageMaterialProperty({
        image: canvas[0],
        transparent: true
      })
    }
  })

  // 取景器镜头聚焦到热力图实例上
  viewerRef.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(
      lonMin + (lonMax - lonMin) / 2,
      latMin + (latMax - latMin) / 2,
      5000000
    ),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: 0
    }
  })
}

// 清空热力图
const resetHeatMap = () => {
  document.querySelector('#heatMap').innerHTML = ''
  viewerRef.entities.remove(heatmapRef)
}

// 盐度api
const getSaltInfo = async () => {
  resetHeatMap()
  let { data } = await saltInfo()
  dvalue.value = "‰"
  // maxValue.value = 40
  // minValue.value = 25
  // let data = saltData
  // const apiData = data.map((item) => ({ ...item, value: item.salt }))
  heatMap2(viewerRef, data)
}
// 温度api
const getTempInfo = async () => {
  resetHeatMap()
  let { data } = await tempInfo()
  dvalue.value = "°C"
  // maxValue.value = 30
  // minValue.value = 0
  // let data = tempData
  // const apiData = data.map((item) => ({ ...item, value: item.temp }))
  heatMap2(viewerRef, data)
}
// 声速api
const getSoundInfo = async () => {
  resetHeatMap()
  let { data } = await soundInfo()
  dvalue.value = "m/s"
  // maxValue.value = 1570
  // minValue.value = 1400
  // let data = soundData
  // const apiData = data.map((item) => ({ ...item, value: item.sound }))
  heatMap2(viewerRef, data)
}
// 密度api
const getFlowInfo = async () => {
  resetHeatMap()
  let { data } = await densityInfo()
  dvalue.value = "g/m^3"
  // maxValue.value = 1060
  // minValue.value = 1000
  // let data = soundData
  // const apiData = data.map((item) => ({ ...item, value: item.vgosa }))
  heatMap2(viewerRef, data)
}
// cesium 缩放
const handleZoom = (zoom) => {
  // 获取当前镜头位置的笛卡尔坐标
  let cameraPos = viewerRef.camera.position

  // 获取当前坐标系标准
  let ellipsoid = viewerRef.scene.globe.ellipsoid

  // 根据坐标系标准，将笛卡尔坐标转换为地理坐标
  let cartographic = ellipsoid.cartesianToCartographic(cameraPos)

  // 获取镜头的高度
  let height = cartographic.height

  // 根据上面当前镜头的位置，获取该中心位置的经纬度坐标
  let centerLon = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(8))
  let centerLat = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(8))

  // 镜头
  viewerRef.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, height * zoom),
    duration: 1.0
  })
}

// export
const getSalt = () => {
  getSaltInfo()
}
const getTemp = () => {
  getTempInfo()
}
const getSound = () => {
  getSoundInfo()
}
const getFlow = () => {
  getFlowInfo()
}
const cesiumPlus = () => {
  handleZoom(0.556)
}
const cesiumSub = () => {
  handleZoom(1.8)
}
const cesiumMeasure = () =>{
  measureLineSpace(viewerRef,Cesium)
}
const getViewerRef = () => {
  return viewerRef
}

defineExpose({
  getSalt,
  getTemp,
  getSound,
  getFlow,
  getViewerRef,
  cesiumPlus,
  cesiumSub,
  cesiumMeasure,
  dvalue,
  maxValue,
  minValue,
})
</script>

<template>
  <div id="cesiumContainer" class="cesium-container"></div>
  <div id="heatMap"></div>
</template>

<style scoped>
:deep(.cesium-popup) {
  z-index: 9999;
}
:deep(.cesium-popup .cesium-popup-background) {
  background: rgba(63, 72, 84, 0.9);
}

:deep(.cesium-popup .cesium-popup-color) {
  color: #ffffff;
}
:deep(.cesium-popup .cesium-popup-content) {
  box-sizing: border-box;
  padding: 10px;
  line-height: 1.4;
  font-size: 13px;
  max-width: 800px;
  min-width: 50px;
}
:deep(.cesium-popup .w-auto) {
  width: auto;
}

.cesium-container {
  width: 100%;
  height: 100%;
  background-color: black;
}
#heatMap {
  width: 1920px;
  height: 1080px;
}
</style>